<script setup>
/**
 * @name 图文剪辑列表
 */

import { computed, onMounted, reactive, ref, nextTick } from "vue";
import {
  CaretRightOutlined,
  CaretLeftOutlined,
  QuestionCircleOutlined,
  PlayCircleOutlined,
  LoadingOutlined
} from "@ant-design/icons-vue";

// 上传启动函数
import uploadStarter from '@/common/utils/uploader/hooks/uploadStarter.js'

// 头部组件
import GraphicTextCutNavBack from "../GraphicTextCut/Components/GraphicTextCutNavBack.vue";
const GraphicTextCutNavBackRef = ref();

// loding 组件
import submitLodingDialog from './submitLodingDialog/index.vue'
const submitLodingDialogRef = ref()

// canvas 组件
import konvaCount from "@/views/shotstack/components/konvaCount/index.vue";
// 实例合集
const konvaCountRefs = ref({});

// 弹窗预览组件
import previewCanvasSwiperDialog from "./previewCanvasSwiperDialog/index.vue";
const previewCanvasSwiperDialogRef = ref();

// 工具
import GTC_tools from "@/views/shotstack/utils/helper.js";

import { useStore } from "vuex";
const store = useStore();
import request from "@/common/utils/request";
import { onBeforeRouteLeave, useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
import { nanoid } from "nanoid";
import { message,  Modal} from "ant-design-vue";
import utils from '@/common/utils/utils.js'


// 充值弹窗
import vipModal from '@/socialMedia/Vip/vipModal.vue'
// 充值弹窗开关
const vipVisible = ref(false)
// 权限数据
const clipRole = computed(() => store.state.user?.clipRole || []);

const state = reactive({
  // 渲染列表
  list: [],
  select_num: 0,
  loading: false,
  // 剪辑项目id
  mainId: '',
  // 标题title
  title: '',
  // 调用oss 获取配置参数接口 需要的 文件夹id
  merchant_folder_statck_id: '',

  // 总共需要上传的 图片张数
  totalUploadNum: 0,
  // 已完成数量
  accomplishNum: 0,
  // 总共勾选的组数
  checkNumber:0
});

const formState = reactive({
  page: 1,
  pageSize: 20,
  total:0,
  last_page:0
});

const backClick = () => {
  router.back(1);
};

// 滚动条向左右滚动
const rollFn = (params = {}) => {
  const { id, type } = params;
  const dom = document.getElementById(id);
  const scrollNum = 120;
  if (dom) {
    if (type === "left") {
      const toNum = (dom.scrollLeft -= scrollNum);
      dom.scrollTo({
        left: toNum,
      });
    } else if (type === "right") {
      const toNum = (dom.scrollLeft += scrollNum);
      dom.scrollTo({
        left: toNum,
      });
    }
  }
};

// 弹窗预览
const toPreview = (item) => {
  previewCanvasSwiperDialogRef.value?.showModal(item);
};

// 将 base64 转为 blob
const  base64ToBlob = (base64Data) => {
    // 从 base64 字符串中提取 MIME 类型和数据部分
    let parts = base64Data.split(';base64,');
    let contentType = parts[0].split(':')[1];
    let raw = window.atob(parts[1]);
    let rawLength = raw.length;
    let uInt8Array = new Uint8Array(rawLength);

    for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }
    // 创建 Blob 对象
    return new Blob([uInt8Array], { type: contentType });
}

// blob 转为文件对象
const blobToFile = (blob, fileName, fileType, uid) => {
  let file = new File([blob], fileName, { type: fileType });
  file.uid = uid
  return file
}

// 处理上传数组结构
const groupArray = (arr, spliceNum=2) => {
  let result = [];
  for (let i = 0; i < arr.length; i += spliceNum) {
    // 使用 slice 方法从当前索引 i 开始，截取长度为 spliceNum 的元素，添加到结果数组中
    result.push(arr.slice(i, i + spliceNum));
  }
  return result;
}

// 截取后缀方法
const getFileExtension = (url) => {
  // 从字符串的最后一个点号开始截取，获取后缀部分
  let parts = url.split('.');
  return parts[parts.length - 1];
}

// 将上传素材 进行同步
const saveImage = async (params) => {
  const { respons } = params
  if (!respons) return
  // 提交的数据
  const submitData = {
  images: respons,
  title: state.title,
  }
  const save = await request.post("/work_ai", "/user/image/clip/save/image", submitData)
  console.log(save, '保存成功了嘛??');
  respons.forEach(ele => {
    ele.uploadStatus = true
  })
}

// 点数信息
const countData = ref(null)

// 点数消耗查询
const pointConsumption = (number) => {

  return new Promise(async(resolve, reject) => {
    const res = await request.get(
      "/work_ai",
      "/user/image/clip/point/get",
      { number}
    );
    countData.value = res
    if (countData.value?.usable != 1) {
        // 打开充值弹窗
      vipVisible.value = true
      reject('点数不足')
      return
    }
    // 获取消耗提示词内容
    const content = utils.useText(countData.value)

    try {      
      // 打开积分消耗提示
      await utils.kd({
        content,
        res:countData.value
      })
      resolve('点数足够,同意消耗')
    } catch (error) {
      reject('不同意消耗')
    }
  })
}

// 确定合成
const submitCreat = async () => {
  console.log(konvaCountRefs.value, "实例合集???");
  //  new Promise(async(res, rej) => {
  // })

  let checkNumber = 0

  const selects = state.list.reduce((access, item) => {
    let ids = []
    if (item?.checked) {
      checkNumber++
      ids = item.resource_data.map(ele => ele.id)
    }
    ids.length && (access = [...access, ...ids])
    return access;
  }, [])

  console.log(selects, 'selects==================需要上传的实例项');
  console.log(checkNumber,'勾选的组数');

  if (!selects.length || !checkNumber) return message.warning('请选择需要合成的图文组!')

  // 点数扣除查询
  await pointConsumption(checkNumber)
  console.log('继续---------');
  console.log('关闭弹窗123123');
  state.checkNumber = checkNumber
  // return

  // 存放 总共需要上传的 图片张数
  state.totalUploadNum = selects.length

  // 打开loading 弹窗
  submitLodingDialogRef.value?.showModal()
  
  setTimeout(() => {
    draw()
  },100)

  const draw = async () => {    
    try {
      let valObj = {};
      for (let key in konvaCountRefs.value) {
        if (selects.includes(key)) {
  
          const {res, parent_id, sort} = await konvaCountRefs.value[key]?.getImgData({ pixelRatio: 3 });
          const blob = base64ToBlob(res)
          const name = `${key}.${blob.type.split('/')[1]}`
          const file = blobToFile(blob, name, blob.type, key)
          // 找到列表中的此项数据, 将此项数据的 item 传递进上传函数中, 等上传完成将 地址存放到这个数据中
          if (!valObj[parent_id]) {
            valObj[parent_id] = []
          }
          valObj[parent_id].push({
            // base64: res,
            // blob,
            file,
            name: `${key}.${blob.type.split('/')[1]}`,
            parent_id,
            sort,
            // 文件夹id
            merchant_folder_statck_id: state.merchant_folder_statck_id
          })
        }
      }
    
      console.log(valObj, "绘制图片的结果??");
  
      const valObjKeys = Object.keys(valObj)
      // return
      if (!valObjKeys.length) return
  
      // 分组拆分
      for (let key in valObj) {
        valObj[key] = groupArray(valObj[key])
      }
  
      // 需要同步到接口的 上传之后的数据
      let submitResponse = {}
  
      for (let key in valObj) {
        let item = valObj[key]
        for (let index = 0; index < item.length; index++) {
          let part = item[index]
  
          console.log(part, '上传的一组数据中的一个片段');
          
          const res =  await uploadStarter.startOssUploads({
            files: part
          })
  
        console.log(res,'oss上传结果---------------------------');
  
          if (Array.isArray(res) && res.length) {
            for (let index = 0; index < res.length; index++) {
              const resItem = res[index];
              const itemResponse = {
                  // 项目id
                image_text_record_id: +state.mainId,
                // 图片组id
                image_text_record_detail_id: resItem.parent_id,
                // 排序值
                sort: resItem.sort,
                // 图片地址
                material_url: resItem.fileUrl,
                // 图片类型
                scene_type: "image",
                // 文件大小 -- 测试用
                material_size:0,
                // 后缀
                material_extension: getFileExtension(resItem.fileUrl),
                // 前端自用 -- 上传是否成功
                uploadStatus:false
              }
  
              if (!submitResponse[resItem.parent_id]) {
                submitResponse[resItem.parent_id] = []
              }
              submitResponse[resItem.parent_id].push(itemResponse)
  
              const findParent = state.list.find(ele => ele.id == resItem.parent_id)
              if (findParent) {              
                const full = submitResponse[resItem.parent_id].length >= findParent.resource_data.length
                if (full) {
                  console.log(submitResponse,'提交的参数');
                  // 该组 已经全部上传完毕, 可以进行同步
                 await saveImage({respons:submitResponse[resItem.parent_id]})
  
                 let accomplishNum = 0
                  // 重新计算 已完成数量
                  for (let key in submitResponse) {
                    const item = submitResponse[key]
                   const isOk =  item.filter(ele => ele?.uploadStatus)
                   accomplishNum += isOk.length
                  }
                  state.accomplishNum = accomplishNum
                  
                }
              }
            }
  
          }
        }
      }
  
      nextTick(() => {
        message.success('保存成功!')
        router.push({
          name: 'ComposeMaterial',
          query: {
            parentType:'图文成片'
          }
        })
      })
  
    } catch (error) {
    } finally {
      submitLodingDialogRef.value?.closeModal()
    }
  }
};



// 选中
const selectItem = (item) => {
  item.checked = !item.checked;
  state.select_num = state.list.filter(ele => ele?.checked)?.length
};

// 全选
const selectAll = (type = "all") => {
  if (type == "推荐成片") {
  } else if (type == "差异度大成片") {
  } else {
  }
  state.list.forEach((ele) => (ele.checked = true));
};

// 数字框 选择合成项
const selectNumBlur = (e) => {
  state.list.forEach((ele, index) => {
    if (index < state.select_num) {
      ele.checked = true;
    } else {
      ele.checked = false;
    }
  });
};

// 处理滚动事件
const handleScroll = (e) => {
  const target = e.target;
  if (target.scrollHeight - target.scrollTop === target.clientHeight && !state.loading) {

    // 已经加载了所有的内容
    if (formState.page >= formState.last_page) return
    formState.page++
    getpreviewList(); // 调用获取数据的函数


    // // 已经加载了所有的内容
    // if (formState.pageSize >= formState.total) return
    
    // if(formState.pageSize + 20 < formState.total) {
    //   // 判断是否触底且不在加载中
    //   formState.pageSize += 10; // 数量增加
    //   getpreviewList(); // 调用获取数据的函数
    // } else {
    //   formState.pageSize = formState.total
    //   getpreviewList(); // 调用获取数据的函数
    // }
  }
};

// 获取列表数据
const getpreviewList = async () => {
  state.loading = true
  try {
    const mainId = route.query?.mainId
    state.mainId = mainId
    console.log(mainId,'要查询的mainId');
    const params = {
      mainId,
      ...formState
    }
    const res = await request.get("/work_ai", "/user/image/clip/privew", params)
    console.log(res, '详情信息??');
    state.list.push(...res.result.data)
    state.merchant_folder_statck_id = res?.merchant_folder_statck_id
    state.title = res.result.data[0]?.title
    formState.total = res.result.total
    formState.last_page = res.result.last_page

  } catch (error) {
  } finally {
  state.loading = false
  }
}

// 初始化 必要数据
const initFn = async () => {
  try {
    await Promise.all([
      store.dispatch("GraphicTextMixCut/getFontList"),
      store.dispatch("GraphicTextMixCut/getFlowerListData"),
    ]);

    // 查询获取预览的数据
    getpreviewList()

  } catch (error) {
    console.log(error);
    message.error("初始化失败");
  }
};

onBeforeRouteLeave((to, from, next) => {

  // 去成片页面, 放行
  if (to.name == 'ComposeMaterial') {
    next(true)
    return
  }

  const id = route.query?.mainId
  console.log(to,'离开的信息');
  // 返回的时候没有携带id
  if (route.query?.mainId && !to.query?.detailId) {
    // 给带上id
    router.push(`/GraphicTextCut?detailId=${id}`)
    next(false)
    return
  }
  // 第二次进来 可以正常离开了
    next(true)
})

onMounted(() => {
  initFn();
});
</script>

<template>

<div class="note_data" v-if="state.loading">
      <div class="loding_content">
        <LoadingOutlined class="loding_icon"></LoadingOutlined>
          <span class="loding_tips">加载中...</span>
      </div>
    </div>

  <a-config-provider prefix-cls="ss">
    <div class="GraphicTextCutPreview">
      <!-- 头部组件 -->
      <GraphicTextCutNavBack
        style="background: #fff; min-width: 1650px; min-height: 64px;"
        ref="GraphicTextCutNavBackRef"
        :leftConfig="{
          isShow: true,
        }"
        :contentConfig="{
          isShow: true,
        }"
        :rightConfig="{
          isShow: true,
        }"
        @backClick="backClick"
      >
        <!-- 头部中间可编辑文本 -->
        <template #content_text>
          <span class="title">{{state.title}}</span>
          <!-- 阿里的页面 -->
        </template>
        <template #right_btns>
          <div class="right_controls">
            <!-- <div class="filter_item">
              <span>推荐成片: <span class="use_num">1</span></span>
              <a-button type="link" class="btn" @click="selectAll('推荐成片')"
                >全部选用</a-button
              >
            </div>
            <div class="filter_item">
              <span>差异度大成片: <span class="use_num">1</span></span>
              <a-button
                type="link"
                class="btn"
                @click="selectAll('差异度大成片')"
                >全部选用</a-button
              >
            </div> -->
            <div class="filter_item" style="gap: 10px">
              <span>选用数量</span>
              <a-input-number
              style="width: 70px"
                size="small"
                v-model:value="state.select_num"
                :min="0"
                :max="state.list.length"
                @blur="selectNumBlur"
              />
            </div>

            <a-button
              style="margin-left: 20px"
              type="primary"
              @click="submitCreat"
            >
              确定合成
              <a-tooltip
                placement="bottomRight"
                :arrowPointAtCenter="true"
                :autoAdjustOverflow="false"
              >
                <template #title>
                  <span>1条图文合成，消耗1创作点</span>
                </template>
                <QuestionCircleOutlined />
              </a-tooltip>
            </a-button>
          </div>
        </template>
      </GraphicTextCutNavBack>

      <div class="center_content" @scroll="handleScroll" v-if="state.list.length" >
        <div
          v-for="item in state.list"
          :key="item.id"
          class="contetn_item"
          @click="selectItem(item)"
        >
          <a-checkbox class="checkbox_item" v-model:checked="item.checked">
            <span style="color: #fff">选用</span>
          </a-checkbox>

          <!-- <div class="preview_icon" @click="preview">

          </div> -->

          <div class="canvas_content">
            <!-- 预览按钮 -->
            <PlayCircleOutlined class="player" @click="toPreview(item)" />

            <!-- 主背景 canvas -->
            <konvaCount
              class="konvaCount"
              :editItem="item.resource_data[0].texts[0]"
              :images="item.resource_data[0].images"
              :pixel="GTC_tools.getPixel(item.resource_data[0].image_tpl)"
              :image_tpl="item.resource_data[0].image_tpl"
              :stickers="item.resource_data[0].stickers"
              :isView="true"
            />

            <template v-if="item.resource_data.length">
              <div class="ather_list">
                <template v-if="item.resource_data.length > 3">
                  <div
                    class="left_lever lever"
                    @click.stop="rollFn({ id: `${item.id}roll`, type: 'left' })"
                  >
                    <CaretLeftOutlined />
                  </div>
                  <div
                    class="right_lever lever"
                    @click.stop="rollFn({ id: `${item.id}roll`, type: 'right' })"
                  >
                    <CaretRightOutlined />
                  </div>
                </template>
                <!-- 底部 canvas列表 -->
                <div class="ather_list_content" :id="`${item.id}roll`">
                  <konvaCount
                    :ref="(el, index) => (konvaCountRefs[ele.id] = el)"
                    v-for="ele in item.resource_data"
                    :key="ele.id"
                    class="mini_konvaCount"
                    :editItem="ele.texts[0]"
                    :images="ele.images"
                    :pixel="GTC_tools.getPixel(ele.image_tpl)"
                    :image_tpl="ele.image_tpl"
                    :stickers="ele.stickers"
                    :isView="true"
                    :parent_id="item.id"
                    :sort="ele.sort"
                  />
                </div>
              </div>
            </template>
          </div>

          <!-- <div class="bottom_msg" v-if="false">
            <div class="tag_list">
              <a-tag color="orange">推荐</a-tag>
              <a-tag color="blue">差异度大</a-tag>
            </div>
          </div> -->
        </div>
      </div>
    </div>
  </a-config-provider>

  <!-- 弹窗预览组件 -->
  <previewCanvasSwiperDialog ref="previewCanvasSwiperDialogRef" />

  <!-- 保存 loading 组件 -->
  <submitLodingDialog 
    :accomplishNum="state.accomplishNum"
    :totalUploadNum="state.totalUploadNum"  
    :checkNumber="state.checkNumber"  
    ref="submitLodingDialogRef"
  >
  </submitLodingDialog>

    <!-- 充值弹窗 -->
    <vipModal :visible="vipVisible" @close="vipVisible = false"></vipModal>

</template>

<style lang="less">
body {
  &::-webkit-scrollbar {
    display: none;
  }
}
</style>

<style lang="less" scoped>

// 加载中 模态框
.note_data{
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.45);
  z-index: 2;

  display: flex;
  justify-content: center;
  align-items: center;
  .loding_content{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 10px;
    color: #fff;
    .loding_tips{
      font-size: 20px;
      font-weight: bold;
    }
    .loding_icon{
      font-size: 30px;

    }
  }
}

.GraphicTextCutPreview {
  height: 100%;
  overflow: hidden;
  background-color: #f2f2f2;
  display: flex;
  flex-direction: column;

  // 头部样式
  .title {
    font-size: 14px;
    font-weight: 600;
  }
  .right_controls {
    display: flex;
    gap: 5px;

    .filter_item {
      display: flex;
      align-items: center;
      gap: 5px;
      margin-right: 10px;
      border: 1px solid #e7e7e7;
      border-radius: 6px;
      padding: 0 10px;
      .use_num {
        font-weight: bold;
        margin-left: 5px;
      }

      .btn {
        padding: 0;
      }
    }
  }

  .center_content {
    // flex: 1;
    overflow-y: auto;
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 20px;
    padding: 10px;
    padding-right: 10px;
    position: relative;

    &::-webkit-scrollbar {
      cursor: pointer;
      width: 8px;
    }

    &::-webkit-scrollbar-thumb {
      background: #c2c2c2;
      /* 滑块的背景颜色 */
      border-radius: 10px;
      /* 滑块的圆角 */
    }

    .contetn_item {
      position: relative;
      background: #fff;
      box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.1);
      cursor: pointer;
      .checkbox_item {
        position: absolute;
        left: 10px;
        top: 10px;
        z-index: 2;
      }

      .canvas_content {
        position: relative;

        &::before {
          content: "";
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          background: rgba(0, 0, 0, 0.3);
          z-index: 1;
          opacity: 0;
          transition: all 0.3s;
        }

        &:hover {
          .player {
            opacity: 1;
          }
          &::before {
            z-index: 1;
            opacity: 1;
          }
        }

        .player {
          opacity: 0;
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          font-size: 60px;
          color: #fff;
          z-index: 1;
          cursor: pointer;
          transition: all 0.3s;
          &:hover {
            color: var(--ss-primary-color-hover);
          }
        }

        .konvaCount {
          zoom: 0.7;
        }

        .mini_konvaCount {
          zoom: 0.15;
        }

        .ather_list {
          overflow-x: auto;
          position: absolute;
          bottom: 0;
          left: 0;
          width: 100%;
          padding: 0 26px;
          z-index: 1;

          .ather_list_content {
            overflow-x: auto;
            display: flex;
            gap: 10px;
            scroll-behavior: smooth;

            // 隐藏滚动条
            &::-webkit-scrollbar {
              display: none;
            }
          }

          // 翻页小把手
          .lever {
            color: #fff;
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            cursor: pointer;
            transition: all 0.3s;
            &:hover{
              color: var(--ss-primary-color-hover);
            }

          }
          .left_lever {
            left: 5px;
          }
          .right_lever {
            right: 5px;
          }
        }
      }

      .bottom_msg {
        display: flex;
        flex-direction: column;
        gap: 5px;
        padding: 8px;
      }
    }
  }
}
</style>
